/**
 * 
 */
package com.example.demo.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.example.demo.service.FlowTaskService;
import com.example.demo.util.FlowNodeVo;

/**
 * @author 030998
 *
 */
@Controller
@RequestMapping("/flowdemo")
public class FlowController {

	@Autowired
	private FlowTaskService flowTaskService;

	@Autowired
	private RepositoryService repositoryService;

	private String processKey = "leave";
	private String businessKey = "123546879";

	/**
	 * deploy
	 */
	@RequestMapping("/deploy")
	@ResponseBody
	public Deployment deploy() {
		Deployment deployment = repositoryService.createDeployment().key("leave").name("leave")
				.addClasspathResource("leave.bpmn20.xml").deploy();
		System.out.println("deployId: " + deployment.getId());

		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
				.deploymentId(deployment.getId()).singleResult();
		System.out.println("Found process definition : " + processDefinition.getName());
		System.out.println("Found process definition : " + processDefinition.getKey());

		Deployment d = repositoryService.createDeploymentQuery().processDefinitionKey(processKey).singleResult();
		System.out.println("Found process definition : " + d.getName());
		System.out.println("Found process definition : " + d.getKey());

		return d;
	}

	@RequestMapping("/start")
	@ResponseBody
	public String start() {
		Map<String, Object> map = getMap();

		String processInstanceId = flowTaskService.start(processKey, businessKey, map);
		System.out.println("processInstanceId:  " + processInstanceId);
		return processInstanceId;
	}

	@RequestMapping("/startAndComplete")
	@ResponseBody
	public String startAndComplete() {
		Map<String, Object> map = getMap();
		flowTaskService.startAndComplete(processKey, businessKey, map);
		return "success";
	}

	@RequestMapping("/claim/{taskId}/{userId}")
	@ResponseBody
	public String claim(@PathVariable("taskId") String taskId, @PathVariable("userId") String userId) {
		// flowTaskService.claim("d5c55915-785b-11ec-bd25-2cf05d15c480", "admin");
		flowTaskService.claim(taskId, userId);
		return "success";
	}

	@RequestMapping("/complete/{taskId}")
	@ResponseBody
	public String complete(@PathVariable("taskId") String taskId) {
		Map<String, Object> map = getMap();
		flowTaskService.complete(taskId, map);
		return "success";
	}

	@RequestMapping("/stop/{processInstanceId}")
	@ResponseBody
	public String stop(@PathVariable("processInstanceId") String processInstanceId) {
		// flowTaskService.stop("494322c4-7900-11ec-8f97-2cf05d15c480", "ddd");
		flowTaskService.stop(processInstanceId, "ddd");
		return "stop success";
	}

	/**
	 * 驳回到前一个节点
	 * @param taskId
	 * @return
	 */
	@RequestMapping("/turnBack/{taskId}")
	@ResponseBody
	public String turnBack(@PathVariable("taskId") String taskId) {
		flowTaskService.turnBack(taskId, getMap());
		return "turnBack success";
	}

	// OK
	/**
	 * 驳回到第一个节点
	 * @param taskId
	 * @return
	 */
	@RequestMapping("/turnBackFirst/{taskId}")
	@ResponseBody
	public String turnBackFirst(@PathVariable("taskId") String taskId) {
		flowTaskService.turnBackFirst(taskId, getMap());
		return "turnBackFirst success";
	}

	/**
	 * 驳回到某个指定节点
	 * @param taskId
	 * @param targetKey
	 * @return
	 */
	@RequestMapping(value = "/flowReturn/{taskId}/{targetKey}")
	@ResponseBody
	public String flowReturn(@PathVariable(value = "taskId") String taskId,
			@PathVariable(value = "targetKey") String targetKey) {
		flowTaskService.flowReturn(taskId, targetKey);
		return "flowReturn success";
	}

	/**
	 * good
	 * 
	 * @param taskId
	 * @return
	 */
	@RequestMapping(value = "/findReturnUserTask/{taskId}")
	@ResponseBody
	public List<FlowNodeVo> findReturnUserTask(@PathVariable(value = "taskId") String taskId) {
		return flowTaskService.findReturnUserTask(taskId);
	}

	/**
	 * 获取当前可以驳回的节点
	 * @param processInstanceId
	 * @param taskId
	 * @return
	 */
	@RequestMapping(value = "/getBackNodesByProcessInstanceId/{processInstanceId}/{taskId}")
	@ResponseBody
	public List<FlowNodeVo> getBackNodesByProcessInstanceId(
			@PathVariable(value = "processInstanceId") String processInstanceId,
			@PathVariable(value = "taskId") String taskId) {
		return flowTaskService.getBackNodesByProcessInstanceId(taskId, processInstanceId);
	}

	/**
	 * 委托
	 * @param taskId
	 * @param userId
	 * @param delegateUserId
	 * @return
	 */
	@RequestMapping(value = "/delegateTask/{taskId}/{userId}/{delegateUserId}")
	@ResponseBody
	public String delegateTask(@PathVariable(value = "taskId") String taskId,
			@PathVariable(value = "userId") String userId,
			@PathVariable(value = "delegateUserId") String delegateUserId) {

		flowTaskService.delegateTask(taskId, userId, delegateUserId);
		return "delegateTask success";
	}

	/**
	 * 处理委托
	 * @param taskId
	 * @return
	 */
	@RequestMapping(value = "/resolveDelegateTask/{taskId}")
	@ResponseBody
	public String resolveDelegateTask(@PathVariable(value = "taskId") String taskId) {
		flowTaskService.resolveDelegateTask(taskId, getMap());
		return "resolveDelegateTask success";
	}

	/**
	 * 转办
	 * @param taskId
	 * @param userId
	 * @param turnToUserId
	 * @return
	 */
	@RequestMapping(value = "/turnTask/{taskId}/{userId}/{turnToUserId}")
	@ResponseBody
	public String turnTask(@PathVariable(value = "taskId") String taskId, @PathVariable(value = "userId") String userId,
			@PathVariable(value = "turnToUserId") String turnToUserId) {
		flowTaskService.turnTask(taskId, userId, turnToUserId);
		
		return "turnTask success";
	}

	private Map<String, Object> getMap() {
		Map<String, Object> map = new HashMap<>();
		map.put("initiator", "jack");
		map.put("leaveDays", "9");
		return map;
	}

}
